#include "ConfigApp.h"
#include "WirelessProtocols/Console.h"
#include "Transceivers/Transceivers.h"
#include "WirelessProtocols/SymbolTime.h"
#include "Transceivers/Security.h"
#include "WirelessProtocols/MCHP_API.h"

#include "TratamentoMemoria.h"
#include <i2c.h>

BOOL lerDado(int *aux) {
    if (!getSemaforoI2C()) {
        setSemaforoI2C(TRUE);
        int config2 = 96;
        int vetorMemoria[tamanhoDaMemoria - 1];
        int config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_REL
                & I2C1_IPMI_DIS & I2C1_7BIT_ADD
                & I2C1_SLW_DIS & I2C1_SM_DIS &
                I2C1_GCALL_DIS & I2C1_STR_DIS &
                I2C1_ACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
                I2C1_STOP_DIS & I2C1_RESTART_DIS
                & I2C1_START_DIS);
        OpenI2C1(config1, config2);
        IdleI2C1();
        StartI2C1();
        while (I2C1CONbits.SEN);
        MasterWriteI2C1(0xA0);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x02);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        IdleI2C1();
        RestartI2C1();
        while (I2C1CONbits.RSEN);
        MasterWriteI2C1(0xA1);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        int j;
        for (j = 0; j < tamanhoDaMemoria - 3; j++) {
            vetorMemoria[j] = MasterReadI2C1();
            while (I2C1STATbits.RBF);
            AckI2C1();
            while (I2C1CONbits.ACKEN);
        }
        vetorMemoria[tamanhoDaMemoria - 2] = MasterReadI2C1();
        while (I2C1STATbits.RBF);
        NotAckI2C1();
        while (I2C1CONbits.ACKEN);
        IdleI2C1();
        StopI2C1();
        while (I2C1CONbits.PEN);
        CloseI2C1();
        BOOL terminouVetor = FALSE;
        BOOL achouHorario = FALSE;
        int temp;
        int vetorHorario[7];
        for (temp = 0; temp < 7; temp++) {
            vetorHorario[temp] = *aux;
            aux++;
        }
        int count = 0;
        while (!(terminouVetor | achouHorario)) {
            if ((vetorMemoria[count] == 0xFF) && (vetorHorario[0] == vetorMemoria[count + 1]) && (vetorHorario[1] == vetorMemoria[count + 2]) && (vetorHorario[2] == vetorMemoria[count + 3]) && (vetorHorario[3] == vetorMemoria[count + 4]) && (vetorHorario[4] == vetorMemoria[count + 5]) && (vetorHorario[5] == vetorMemoria[count + 6]) && (vetorMemoria[count + 7] == vetorHorario[6])) {
                achouHorario = TRUE;
            } else {
                count++;
            }
            if (count == tamanhoDaMemoria - 9) {
                terminouVetor = TRUE;
            }
        }
        if (achouHorario) {
            count = count + 8;
            int vetorTempMedida[30];
            int tempCountCopia = 0;
            BOOL acheiFF = FALSE;
            BOOL chegueiNoFinal = FALSE;
            while (!(acheiFF | chegueiNoFinal)) {
                if (!(vetorMemoria[count] == 0xFF)) {
                    vetorTempMedida[tempCountCopia] = vetorMemoria[count];
                } else {
                    vetorTempMedida[tempCountCopia] = vetorMemoria[count];
                    acheiFF = TRUE;
                }
                tempCountCopia++;
                count++;
                if (tempCountCopia == 29) {
                    chegueiNoFinal = TRUE;
                }
            }
            if (!chegueiNoFinal) {
                vetorTempMedida[tempCountCopia] = vetorMemoria[count];
                int tempCountCopia2;
                for (tempCountCopia2 = 0; tempCountCopia2 < tempCountCopia; tempCountCopia2++) {
                    MiApp_WriteData(vetorTempMedida[tempCountCopia2]);
                }
				setSemaforoI2C(FALSE);
                return TRUE;
            } else {
				setSemaforoI2C(FALSE);
                return FALSE;
            }
        } else {
			setSemaforoI2C(FALSE);
            return FALSE;
        }
    } else {
		setSemaforoI2C(FALSE);
        return FALSE;
    }
}

void iniciaMemoria(void) {
    if (!getSemaforoI2C()) {
        setSemaforoI2C(TRUE);
        int config2 = 96;
        /* Configure I2C for 7 bit address mode  */
        int config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_REL
                & I2C1_IPMI_DIS & I2C1_7BIT_ADD
                & I2C1_SLW_DIS & I2C1_SM_DIS &
                I2C1_GCALL_DIS & I2C1_STR_DIS &
                I2C1_ACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
                I2C1_STOP_DIS & I2C1_RESTART_DIS
                & I2C1_START_DIS);
        OpenI2C1(config1, config2);
        IdleI2C1();
        StartI2C1();
        while (I2C1CONbits.SEN);
        MasterWriteI2C1(0xA0);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x00);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x00);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x02);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        IdleI2C1();
        StopI2C1();
        while (I2C1CONbits.PEN);
        CloseI2C1();
        setSemaforoI2C(FALSE);
    }
}

void iniciaMemoria2(void) {
    IdleI2C1();
    StartI2C1();
    while (I2C1CONbits.SEN);
    MasterWriteI2C1(0xA0);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    MasterWriteI2C1(0x00);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    MasterWriteI2C1(0x00);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    MasterWriteI2C1(0x02);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    IdleI2C1();
    StopI2C1();
    while (I2C1CONbits.PEN);
}

BOOL verificaMemoria(void) {
    if (!getSemaforoI2C()) {
        setSemaforoI2C(TRUE);
        int pagina;
        int posMem;
        int config2 = 96;
        int config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_REL
                & I2C1_IPMI_DIS & I2C1_7BIT_ADD
                & I2C1_SLW_DIS & I2C1_SM_DIS &
                I2C1_GCALL_DIS & I2C1_STR_DIS &
                I2C1_ACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
                I2C1_STOP_DIS & I2C1_RESTART_DIS
                & I2C1_START_DIS);
        OpenI2C1(config1, config2);
        IdleI2C1();
        StartI2C1();
        while (I2C1CONbits.SEN);
        MasterWriteI2C1(0xA0);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x00);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        IdleI2C1();
        RestartI2C1();
        while (I2C1CONbits.RSEN);
        MasterWriteI2C1(0xA1);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        pagina = MasterReadI2C1();
        while (I2C1STATbits.RBF);
        AckI2C1();
        while (I2C1CONbits.ACKEN);
        posMem = MasterReadI2C1();
        while (I2C1STATbits.RBF);
        NotAckI2C1();
        while (I2C1CONbits.ACKEN);
        IdleI2C1();
        StopI2C1();
        while (I2C1CONbits.PEN);
        CloseI2C1();
        setSemaforoI2C(FALSE);
        if ((posMem == 2) && (pagina == 0)) {
            return TRUE;
        } else {
            return FALSE;
        }
    } else {
        return FALSE;
    }
}

BOOL lerPaginaEPosPagina(int *PaginaPosPagina) {
    IdleI2C1();
    StartI2C1();
    while (I2C1CONbits.SEN);
    MasterWriteI2C1(0xA0);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    MasterWriteI2C1(0x00);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    IdleI2C1();
    RestartI2C1();
    while (I2C1CONbits.RSEN);
    MasterWriteI2C1(0xA1);
    while (I2C1STATbits.TBF);
    while (I2C1STATbits.ACKSTAT);
    (*PaginaPosPagina) = MasterReadI2C1();
    PaginaPosPagina++;
    while (I2C1STATbits.RBF);
    AckI2C1();
    while (I2C1CONbits.ACKEN);
    (*PaginaPosPagina) = MasterReadI2C1();
    while (I2C1STATbits.RBF);
    NotAckI2C1();
    while (I2C1CONbits.ACKEN);
    IdleI2C1();
    StopI2C1();
    while (I2C1CONbits.PEN);
    return TRUE;
}

BOOL lerMemoria(int *aux) {
    if (!getSemaforoI2C()) {
        setSemaforoI2C(TRUE);
        int config2 = 96;
        int config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_REL
                & I2C1_IPMI_DIS & I2C1_7BIT_ADD
                & I2C1_SLW_DIS & I2C1_SM_DIS &
                I2C1_GCALL_DIS & I2C1_STR_DIS &
                I2C1_ACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
                I2C1_STOP_DIS & I2C1_RESTART_DIS
                & I2C1_START_DIS);
        OpenI2C1(config1, config2);
        IdleI2C1();
        StartI2C1();
        while (I2C1CONbits.SEN);
        MasterWriteI2C1(0xA0);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x00);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        IdleI2C1();
        RestartI2C1();
        while (I2C1CONbits.RSEN);
        MasterWriteI2C1(0xA1);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        int j;
        for (j = 0; j < 20; j++) {
            *aux = MasterReadI2C1();
            while (I2C1STATbits.RBF);
            AckI2C1();
            while (I2C1CONbits.ACKEN);
            aux++;
        }
        *aux = MasterReadI2C1();
        while (I2C1STATbits.RBF);
        NotAckI2C1();
        while (I2C1CONbits.ACKEN);
        IdleI2C1();
        StopI2C1();
        while (I2C1CONbits.PEN);
        CloseI2C1();
        setSemaforoI2C(FALSE);
        return TRUE;
    } else {
        return FALSE;
    }
}

BOOL lerDado2(int *aux) {
     if (!getSemaforoI2C()) {
        setSemaforoI2C(TRUE);
        int config2 = 96;
        int config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_REL
                & I2C1_IPMI_DIS & I2C1_7BIT_ADD
                & I2C1_SLW_DIS & I2C1_SM_DIS &
                I2C1_GCALL_DIS & I2C1_STR_DIS &
                I2C1_ACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
                I2C1_STOP_DIS & I2C1_RESTART_DIS
                & I2C1_START_DIS);
        OpenI2C1(config1, config2);
        IdleI2C1();
        StartI2C1();
        while (I2C1CONbits.SEN);
        MasterWriteI2C1(0xA0);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        MasterWriteI2C1(0x02);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        IdleI2C1();
        RestartI2C1();
        while (I2C1CONbits.RSEN);
        MasterWriteI2C1(0xA1);
        while (I2C1STATbits.TBF);
        while (I2C1STATbits.ACKSTAT);
        int j;
        for (j = 0; j < 19; j++) {
            *aux = MasterReadI2C1();
            while (I2C1STATbits.RBF);
            aux++;
            AckI2C1();
            while (I2C1CONbits.ACKEN);
        }
		*aux = MasterReadI2C1();
        while (I2C1STATbits.RBF);
        NotAckI2C1();
        while (I2C1CONbits.ACKEN);
        IdleI2C1();
        StopI2C1();
        while (I2C1CONbits.PEN);
        CloseI2C1();
        setSemaforoI2C(FALSE);
        return TRUE;
    } else {
        return FALSE;
    }
}
